package cn.commonblog.common.config;

import cn.commonblog.common.entity.BaseEntity;
import com.baomidou.mybatisplus.autoconfigure.MybatisPlusAutoConfiguration;
import com.baomidou.mybatisplus.autoconfigure.MybatisPlusProperties;
import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
import com.baomidou.mybatisplus.extension.plugins.OptimisticLockerInterceptor;
import com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.reflection.MetaObject;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import org.springframework.boot.autoconfigure.AutoConfigureOrder;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.ComponentScans;
import org.springframework.context.annotation.Configuration;
import org.springframework.transaction.annotation.EnableTransactionManagement;

import javax.annotation.Resource;
import java.util.Date;

/**
 * Mybatis Plus配置
 *
 * @author zhoudi
 * @date 2020/6/27
 */
@Slf4j
@Configuration
@AutoConfigureOrder
@EnableTransactionManagement
@MapperScan("cn.commonblog.biz.mapper")
// Service包扫描
@ComponentScans({
        @ComponentScan("cn.commonblog.biz.service")
})
@AutoConfigureAfter(MybatisPlusAutoConfiguration.class)
public class MybatisPlusConfig {

    @Resource
    private MybatisPlusProperties mybatisPlusProperties;


    public MybatisPlusConfig(MybatisPlusProperties mybatisPlusProperties) {
        this.mybatisPlusProperties = mybatisPlusProperties;
    }

    /**
     * Mybatis-Plus 基础字段
     */
    @Bean
    MetaObjectHandler myMetaObjectHandler() {
        log.debug("==========================myMetaObjectHandler init==========================");

        final String entityFieldNameDateCreated = "dateCreated";
        final String entityFieldNameLastUpdated = "lastUpdated";
        final String entityFieldNameDeleteFlag = "deleteFlag";
        final String entityFieldNameVersion = "version";

        return new MetaObjectHandler() {
            @Override
            public void insertFill(MetaObject metaObject) {
                Date now = new Date();
                this.setFieldValByName(entityFieldNameDateCreated, now, metaObject);
                this.setFieldValByName(entityFieldNameLastUpdated, now, metaObject);
                //添加数据时，delete_flag默认填充为0
                this.setFieldValByName(entityFieldNameDeleteFlag, BaseEntity.DELETE_FLAG_FALSE, metaObject);
                //添加数据时，version默认填充为1
                this.setFieldValByName(entityFieldNameVersion, 1, metaObject);
            }

            @Override
            public void updateFill(MetaObject metaObject) {
                Date now = new Date();

                //TODO 因为执行数据填充在执行sql之前，实际deleteFlag还是原来的，若要使用，先将deleteFlag set 1
                //逻辑删除的删除日期
//                Integer deleteFlag = (Integer) this.getFieldValByName(entityFieldNameDeleteFlag, metaObject);
//                if (deleteFlag == BaseEntity.DELETE_FLAG_TRUE && this.getFieldValByName(entityFieldNameDeleteDate, metaObject) == null) {
//                    this.setFieldValByName(entityFieldNameDeleteDate, now, metaObject);
//                }

                this.setFieldValByName(entityFieldNameLastUpdated, now, metaObject);
            }
        };
    }

    /**
     * 启用乐观锁插件
     *
     * @return
     */
    @Bean
    @ConditionalOnMissingBean(OptimisticLockerInterceptor.class)
    public OptimisticLockerInterceptor optimisticLockerInterceptor() {
        return new OptimisticLockerInterceptor();
    }

    /**
     * Mybatis-Plus 分页插件
     */
    @Bean
    public PaginationInterceptor paginationInterceptor() {
        return new PaginationInterceptor();
    }

}
